package ms.unicorn.modellanguage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import ms.unicorn.Element;
import ms.unicorn.Relation;
import ms.unicorn.diagram.part.UnicornDiagramEditorPlugin;
import ms.unicorn.modellanguage.LanguageRelation.RelationStyle;
import ms.unicorn.ui.figures.ConnectionFigure;
import ms.unicorn.util.ViewUtil;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.ui.preferences.IPreferenceConstants;
import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities;
import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx;
import org.eclipse.gmf.runtime.notation.Connector;
import org.eclipse.gmf.runtime.notation.FontStyle;
import org.eclipse.gmf.runtime.notation.NotationFactory;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
import org.eclipse.gmf.runtime.notation.Routing;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.FontData;

public class LanguageRelationEditHelperAdvice extends
		LanguageElementEditHelperAdvice {
	public static final String FIGURE_CONNECTION = "connection";
	
	public static final LanguageRelationEditHelperAdvice DefaultInstance = new LanguageRelationEditHelperAdvice();
	
	public LanguageRelationEditHelperAdvice() {
		
	}
	
	public boolean checkRelationConstraints(Element container,
			Relation linkInstance, Element source, Element target) {
		return true;
	}

	@Override
	public Map<String, IFigure> createFigures(EditPart context,
			Element element, EditPart elementEditPart) {
		Map<String, IFigure> figures = new HashMap<String, IFigure>();
		PolylineConnectionEx figure = new ConnectionFigure();
		figures.put(FIGURE_CONNECTION, figure);
		LanguageElement relElement = LanguageRegistry.INSTANCE.getLanguageElement(element);
		if (relElement instanceof LanguageRelation) {
			LanguageRelation rel = (LanguageRelation) relElement;
			Relation domainRel = (Relation) element;
			RelationStyle style = rel.getRelationStyle(domainRel.getSource(), domainRel.getTarget());
			figure.setLineStyle(style.getLineStyle());
			figure.setLineWidth(style.getLineWidth());
			
			for(DecoratorProxy decor: relElement.getDecorators())
				decor.createDecoration(figure);
			
			for (DecoratorProxy decor: style.decorators)
				decor.createDecoration(figure);
			
		}
		return figures;
	}

	@Override
	public View createView(IAdaptable semanticAdapter, View containerView, String semanticHint,
			int index, boolean persisted, PreferencesHint preferencesHint) {
		Element domainElement = (Element)getSemanticElement(semanticAdapter);
		if (domainElement instanceof Relation)
			return createEdge((Relation)domainElement, containerView, semanticHint, 
					index, persisted, preferencesHint);
		return null;
	}
	
	@SuppressWarnings("unchecked")
	protected View createEdge(Relation domainElement, View containerView, String semanticHint,
			int index, boolean persisted, PreferencesHint preferencesHint) {
		Connector edge = NotationFactory.eINSTANCE.createConnector();
		edge.getStyles().add(NotationFactory.eINSTANCE.createFontStyle());
		
		RelativeBendpoints bendpoints = NotationFactory.eINSTANCE
				.createRelativeBendpoints();
		ArrayList<RelativeBendpoint> points = new ArrayList<RelativeBendpoint>(
				2);
		points.add(new RelativeBendpoint());
		points.add(new RelativeBendpoint());
		bendpoints.setPoints(points);
		edge.setBendpoints(bendpoints);
		ViewUtil.insertChildView(containerView, edge, index, persisted);
		edge.setType("ms.unicorn.Relation");
		edge.setElement(domainElement);

		if (preferencesHint == null)
			preferencesHint = UnicornDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT;
		
		// initializePreferences
		final IPreferenceStore prefStore = (IPreferenceStore) preferencesHint
				.getPreferenceStore();
	
		org.eclipse.swt.graphics.RGB lineRGB = PreferenceConverter.getColor(
				prefStore, IPreferenceConstants.PREF_LINE_COLOR);
		ViewUtil.setStructuralFeatureValue(edge,
				NotationPackage.eINSTANCE.getLineStyle_LineColor(),
				FigureUtilities.RGBToInteger(lineRGB));
		FontStyle edgeFontStyle = (FontStyle) edge
				.getStyle(NotationPackage.Literals.FONT_STYLE);
		if (edgeFontStyle != null) {
			FontData fontData = PreferenceConverter.getFontData(prefStore,
					IPreferenceConstants.PREF_DEFAULT_FONT);
			edgeFontStyle.setFontName(fontData.getName());
			edgeFontStyle.setFontHeight(fontData.getHeight());
			edgeFontStyle.setBold((fontData.getStyle() & SWT.BOLD) != 0);
			edgeFontStyle.setItalic((fontData.getStyle() & SWT.ITALIC) != 0);
			org.eclipse.swt.graphics.RGB fontRGB = PreferenceConverter
					.getColor(prefStore, IPreferenceConstants.PREF_FONT_COLOR);
			edgeFontStyle.setFontColor(FigureUtilities.RGBToInteger(fontRGB)
					.intValue());
		}
		Routing routing = Routing.get(prefStore
				.getInt(IPreferenceConstants.PREF_LINE_STYLE));
		if (routing != null) {
			ViewUtil.setStructuralFeatureValue(edge,
					NotationPackage.eINSTANCE.getRoutingStyle_Routing(),
					routing);
		}
		/*Node label6001 = ViewUtil.createLabel(edge,
				UnicornVisualIDRegistry
						.getType(RelationElementTypeEditPart.VISUAL_ID));
		label6001.setLayoutConstraint(NotationFactory.eINSTANCE
				.createLocation());
		Location location6001 = (Location) label6001.getLayoutConstraint();
		location6001.setX(0);
		location6001.setY(40);*/
		return edge;
	}
	
}
